﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Text;
using Microsoft.SqlServer.Management.Trace;
using Microsoft.SqlServer.Management.Common;

namespace SqlWatcher
{
    internal class SqlReader
    {
        private static bool BackgroundThreadStop = false;
        private object QueueLock = new object();
        private static List<object[]> EventQueue = new List<object[]>();
        private System.Threading.Thread backgroundThread;
        private System.Threading.Thread backgroundThread2;
        //private static System.Threading.Thread backgroundThread = new System.Threading.Thread(BackgroundThread);
        //private static System.Threading.Thread backgroundThread2 = new System.Threading.Thread(BackgroundThread2);
        private IPAddress _ipAddress;
        private Int32 _port;
        private static bool isStopped = false;
        private string _startup = null;
        
        internal  void Start(string conn)
        {
            _startup = conn;
            backgroundThread = new System.Threading.Thread(BackgroundThread);
            backgroundThread2 = new System.Threading.Thread(BackgroundThread2);
            backgroundThread2.Start();
            backgroundThread.Start();

            

        }

        public static void StartProcessing()
        {

        }
        internal void Stop()
        {
            backgroundThread2.Abort();
            backgroundThread.Abort();
        }

        private void BackgroundThread2()
        {
            TraceServer reader = new TraceServer();
            string[] connParams = _startup.Split('|');

            while (!isStopped)
            {



                try
                {

                    ConnectionInfoBase ci = new SqlConnectionInfo(connParams[0]);
                    _ipAddress = IPAddress.Parse(connParams[1]);
                    _port = Int32.Parse(connParams[2]);
                    ((SqlConnectionInfo)ci).UseIntegratedSecurity = true;
                    //((SqlConnectionInfo)ci).ConnectionProtocol = NetworkProtocol.TcpIp;
                    //  MaxPoolSize set low to reduce connections, set on  Thursday after session connection errors first occurred
                    ((SqlConnectionInfo)ci).MaxPoolSize = 1;
                    ((SqlConnectionInfo)ci).PacketSize = 32767;


                    reader.InitializeAsReader(ci, @"IT_Sabotage.tdf");

                    while (reader.Read())
                    {
                        // put line into array
                        Object[] values = new Object[reader.FieldCount];
                        for (int i = 0; i < reader.FieldCount; i++)
                        {
                            values[i] = reader.GetValue(i);
                            //reader.GetValues(values);


                        }

                        // add array to queue
                        lock (QueueLock)
                        {
                            EventQueue.Add(values);
                        }
                        values = null;
                    }
                    reader.Close();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(connParams[0] + ex.Message + ex.InnerException + ex.StackTrace);
                    System.Threading.Thread.Sleep(5000);
                }
                // need a finally to clean up resources, reader may not reset after an error
                //finally
                //{
                //    reader.Close();
                //    reader = null;

                //}
            } 
        }

        private void BackgroundThread()
        {
            while (!BackgroundThreadStop)
            {
                bool shouldSleep = true;

                lock (QueueLock)
                {

                    if (EventQueue.Count != 0)
                    {
                        shouldSleep = false;

                    }
                }

                if (shouldSleep)
                {
                    System.Threading.Thread.Sleep(10000);
                }
                else // should process the queue
                {
                    List<object[]> ourQueue;
                    lock (QueueLock)
                    {
                        // swap queues, giving the capture callback a new one
                        ourQueue = EventQueue;
                        EventQueue = new List<object[]>();
                        ArrayList input = new ArrayList { ourQueue, _ipAddress, _port };
                        //ThreadHelper.StartSocketSend((object)input);
                        SocketSendHelper.SendEvent((object)input);
                    }
                }
            }

        }
    }
}
